

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" href="/img/favicon.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="Fly542">
  <meta name="keywords" content="">
  
    <meta name="description" content="源码分析重要结构体说明   结构体名 定义位置 说明    query_info util&#x2F;data&#x2F;msgreply.h 存储DNS查询信息的结构体   reply_info util&#x2F;data&#x2F;msgreply.h 存储DNS查询和回复数据包的结构   comm_point util&#x2F;netevent.h 和网络通信有关的结构体   初始化核心流程123456789101112131415ma">
<meta property="og:type" content="article">
<meta property="og:title" content="unbound源码分析">
<meta property="og:url" content="http://fly542.cn/2023/04/10/03%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/07%E5%BA%94%E7%94%A8%E8%BD%AF%E4%BB%B6/unbound%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Fly542 技术沉淀">
<meta property="og:description" content="源码分析重要结构体说明   结构体名 定义位置 说明    query_info util&#x2F;data&#x2F;msgreply.h 存储DNS查询信息的结构体   reply_info util&#x2F;data&#x2F;msgreply.h 存储DNS查询和回复数据包的结构   comm_point util&#x2F;netevent.h 和网络通信有关的结构体   初始化核心流程123456789101112131415ma">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-04-10T01:18:04.000Z">
<meta property="article:modified_time" content="2025-05-21T08:48:29.298Z">
<meta property="article:author" content="Fly542">
<meta property="article:tag" content="dns">
<meta property="article:tag" content="unbound">
<meta name="twitter:card" content="summary_large_image">
  
  
  <title>unbound源码分析 - Fly542 技术沉淀</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4/github-markdown.min.css" />
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hint.css@2/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css" />
  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"fly542.cn","root":"/","version":"1.8.14","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 6.0.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>Fly542 技术沉淀</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="unbound源码分析">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2023-04-10 09:18" pubdate>
        2023年4月10日 上午
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      6.8k 字
    </span>
  

  
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      57 分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">unbound源码分析</h1>
            
            <div class="markdown-body">
              <h1 id="源码分析"><a href="#源码分析" class="headerlink" title="源码分析"></a>源码分析</h1><h2 id="重要结构体说明"><a href="#重要结构体说明" class="headerlink" title="重要结构体说明"></a>重要结构体说明</h2><table>
<thead>
<tr>
<th>结构体名</th>
<th>定义位置</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>query_info</td>
<td>util/data/msgreply.h</td>
<td>存储DNS查询信息的结构体</td>
</tr>
<tr>
<td>reply_info</td>
<td>util/data/msgreply.h</td>
<td>存储DNS查询和回复数据包的结构</td>
</tr>
<tr>
<td>comm_point</td>
<td>util/netevent.h</td>
<td>和网络通信有关的结构体</td>
</tr>
</tbody></table>
<h2 id="初始化核心流程"><a href="#初始化核心流程" class="headerlink" title="初始化核心流程"></a>初始化核心流程</h2><figure class="highlight stylus"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></div></td><td class="code"><pre><code class="hljs stylus">main---------------------------------------unbound<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">// 程序入口</span><br>    run_daemon-----------------------------unbound<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">// 启动守护服务</span><br>        daemon_open_shared_ports-------unbound<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">// 打开监听端口</span><br>        daemon_fork------------------------daemon<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 启动服务</span><br>                daemon_create_workers----------daemon<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 创建工作线程对象和资源</span><br>                        worker_create--------------worker<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 创建各个工作线程对象，每个对象负责部分部分临时端口数据</span><br>														<span class="hljs-comment">// 的接收和发送</span><br>                worker_init--------------------worker<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 工作线程初始化，worker_start_accept，</span><br>                        worker_start_accept--------worker<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 启动监听并accept</span><br>                        worker_handle_request------worker<span class="hljs-selector-class">.c</span>     <span class="hljs-comment">// 请求处理函数</span><br>                        tube_setup_bg_listen-------util/tube<span class="hljs-selector-class">.c</span>  <span class="hljs-comment">// 管理命令后台监听服务</span><br>                daemon_start_others(daemon)---------daemon<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">// 启动非主线程的其他工作线程</span><br>                        thread_start--------------------daemon<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">//线程工作函数</span><br>                                worker_work(worker)---------wroker<span class="hljs-selector-class">.c</span>    <span class="hljs-comment">// 工作线程进入工作循环</span><br>                worker_work(daemon-&gt;workers<span class="hljs-selector-attr">[0]</span>)-----worker<span class="hljs-selector-class">.c</span>   <span class="hljs-comment">// 启动主工作线程循环处理事件，大家都监听udp端口进行数据循环处理</span><br></code></pre></td></tr></table></figure>

<h2 id="工作线程循环处理事件"><a href="#工作线程循环处理事件" class="headerlink" title="工作线程循环处理事件"></a>工作线程循环处理事件</h2><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">main<span class="hljs-params">---------daemon/unbound</span>.c<br>    run_daemon<span class="hljs-params">---------daemon/unbound</span>.c<br>        daemon_fork <span class="hljs-params">--------------daemon/daemon</span>.c<br>            worker_work<span class="hljs-params">-----worker</span>.c<br>                comm_base_dispatch<span class="hljs-params">----------util/netevent</span>.c<br>                    ub_event_base_dispatch<span class="hljs-params">-------util/ub_event</span>.c   <span class="hljs-string">//</span> 事件封装<br>                        event_base_dispatch<span class="hljs-params">------util/mini_event</span>.c <span class="hljs-string">//</span> 进入while事件循环处理过程 《事件处理可替换为libevent》<br>                            handle_select<span class="hljs-params">--------util/mini_event</span>.c  <span class="hljs-string">//</span> 调用selec阻塞等待事件并回调处理函数<br></code></pre></td></tr></table></figure>

<h2 id="开启端口监听过程"><a href="#开启端口监听过程" class="headerlink" title="开启端口监听过程"></a>开启端口监听过程</h2><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">main<span class="hljs-params">---------------------------------------unbound</span>.c    <span class="hljs-string">//</span> 程序入口<br>    run_daemon<span class="hljs-params">-----------------------------unbound</span>.c    <span class="hljs-string">//</span> 启动守护服务<br>        daemon_open_shared_ports<span class="hljs-params">-------unbound</span>.c    <span class="hljs-string">//</span> 打开监听端口<br>            listening_ports_open<span class="hljs-params">-------services/listen_dnsport</span>.c <span class="hljs-string">//</span>开启端口监听<br>                ports_create_<span class="hljs-keyword">if</span><span class="hljs-params">--------services/listen_dnsport</span>.c <br>                    。。。。<span class="hljs-params">--------services/listen_dnsport</span>.c<br>                     make_sock<span class="hljs-params">--------services/listen_dnsport</span>.c   <span class="hljs-string">//</span>创建tcp和udp端口监听句柄到<br>                   port_insert<span class="hljs-params">--------services/listen_dnsport</span>.c   <span class="hljs-string">//</span>将创建的端口监听对象加入到daemon-&gt;ports中,在《tcp 及udp事件处理回调函数的设置》中将ports加入到事件循环中<br></code></pre></td></tr></table></figure>

<h2 id="tcp-及udp事件处理回调函数的设置"><a href="#tcp-及udp事件处理回调函数的设置" class="headerlink" title="tcp 及udp事件处理回调函数的设置"></a>tcp 及udp事件处理回调函数的设置</h2><figure class="highlight xl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs xl">worker_init-------------------------------daemon/worker.c<br>    listen_create(ports, worker_handle_request)-------------------------services/listen_dnsport.c <span class="hljs-comment">// 创建监听对象,并设置监听回调函数为 worker_handle_request</span><br>	    comm_point_create_udp_ancil-------util/netevent.c             <span class="hljs-comment">// 创建udp通信辅助事件， 配置文件中的interface-automatic 设置为yes则调用此函数</span><br>			<span class="hljs-function"><span class="hljs-title">c</span>-&gt;</span>callback = callback; <span class="hljs-comment">// 设置udp回调函数</span><br>            <span class="hljs-function"><span class="hljs-title">c</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">ev</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">ev</span> = ub_event_new(xxx, comm_point_udp_ancil_callback)   // 创建事件管理对象，和c关联, 在 comm_point_udp_ancil_callback 中回调到c-&gt;</span>callback函数 worker_handle_request<br>            ub_event_add() -------------util/netevent.c              <span class="hljs-comment">// 将udp句柄加入事件监听循环中</span><br>                event_add---------------util/mini_event.c           <span class="hljs-comment">// 加入监听队列</span><br>        comm_point_create_udp-------------util/netevent.c             <span class="hljs-comment">// 创建udp事件</span><br>            <span class="hljs-function"><span class="hljs-title">c</span>-&gt;</span>callback = callback; <span class="hljs-comment">// 设置udp回调函数</span><br>            <span class="hljs-function"><span class="hljs-title">c</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">ev</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">ev</span> = ub_event_new(xxx, comm_point_udp_callback)   // 创建事件管理对象，和c关联, comm_point_udp_callback中会回调到c-&gt;</span>callback函数<br>            ub_event_add() -------------util/netevent.c              <span class="hljs-comment">// 将udp句柄加入事件监听循环中</span><br>                event_add---------------util/mini_event.c           <span class="hljs-comment">// 加入监听队列</span><br><br>        comm_point_create_tcp---------------util/netevent.c       <span class="hljs-comment">// 创建tcp事件</span><br>            <span class="hljs-function"><span class="hljs-title">c</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">ev</span>-&gt;</span>ev = = ub_event_new(comm_point_tcp_accept_callback) <span class="hljs-comment">// 设置tcp accept请求回调处理函数</span><br>            ub_event_add()------------util/netevent.c              <span class="hljs-comment">// 将udp句柄加入事件监听循环中</span><br>             .....<br></code></pre></td></tr></table></figure>

<h2 id="module创建及调用过程"><a href="#module创建及调用过程" class="headerlink" title="module创建及调用过程"></a>module创建及调用过程</h2><p>module创建及初始化</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs awk">daemon_fork--------------------------------------------daemon/daemon.c<br>	daemon_setup_modules------------------------------daemon/daemon.c<br>		modstack_setup---------------------------------services/modstack.c<br>			modstack_config<br>				module_factory  <span class="hljs-regexp">//</span> module创建工厂,创建所有module<br>					module_funcs_avail <span class="hljs-regexp">//</span>创建所有module列表<br>						dns64_get_funcblock <span class="hljs-regexp">//</span> <br>						subnetmod_get_funcblock <span class="hljs-regexp">//</span> 创建edns-subnet 模块<br>						respip_get_funcblock<br>						val_get_funcblock<br>						iter_get_funcblock <span class="hljs-regexp">//</span> 创建iterator <br>			<span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;stack-&gt;num; i++) &#123;<br>				<span class="hljs-keyword">if</span>(!(*stack-&gt;mod[i]-&gt;init)(env, i)) &#123; <span class="hljs-regexp">//</span> 调用各个module的init函数<br>			&#125;<br></code></pre></td></tr></table></figure>
<p>module执行</p>
<figure class="highlight xl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs xl">mesh_run------------------------------------services/mesh.c<br>	<span class="hljs-keyword">while</span>(mstate) &#123; <span class="hljs-comment">// 运行各个module的operator函数,如iter_operator/subnetmod_operate</span><br>		fptr_ok(fptr_whitelist_mod_operate(<br>		<span class="hljs-function"><span class="hljs-title">mesh</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">mods</span>.<span class="hljs-built_in">mod</span>[mstate-&gt;</span><span class="hljs-function"><span class="hljs-title">s</span>.curmod]-&gt;</span>operate));<br>		(*<span class="hljs-function"><span class="hljs-title">mesh</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">mods</span>.<span class="hljs-built_in">mod</span>[mstate-&gt;</span><span class="hljs-function"><span class="hljs-title">s</span>.curmod]-&gt;</span>operate)<br>			(&amp;<span class="hljs-function"><span class="hljs-title">mstate</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">s</span>, ev, mstate-&gt;</span>s.curmod, e); <span class="hljs-comment">// 执行</span><br>	&#125;<br></code></pre></td></tr></table></figure>

<h2 id="客户端udp请求处理过程"><a href="#客户端udp请求处理过程" class="headerlink" title="客户端udp请求处理过程"></a>客户端udp请求处理过程</h2><figure class="highlight xl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xl">worker_handle_request-------daemon/worker.c           <span class="hljs-comment">// udp请求处理回调函数</span><br>    mesh_new_client-------------services/mesh.c           <span class="hljs-comment">// 创建来自客户端的新查询</span><br>        mesh_run()--------------services/mesh.c           <span class="hljs-comment">// 遍历所有模块进行数据处理，如subnetcache、validator、iterator</span><br>			(*<span class="hljs-function"><span class="hljs-title">mesh</span>-&gt;</span><span class="hljs-function"><span class="hljs-title">mods</span>.<span class="hljs-built_in">mod</span>[mstate-&gt;</span><span class="hljs-function"><span class="hljs-title">s</span>.curmod]-&gt;</span><span class="hljs-function"><span class="hljs-title">operate</span>)(&amp;mstate-&gt;</span><span class="hljs-function"><span class="hljs-title">s</span>, ev, mstate-&gt;</span>s.curmod, e);  <span class="hljs-comment">// 回调各个模块的operate函数，如subnetmod_operate、iterator_operate</span><br>          <br></code></pre></td></tr></table></figure>

<h3 id="iterator-处理过程"><a href="#iterator-处理过程" class="headerlink" title="iterator 处理过程"></a>iterator 处理过程</h3><figure class="highlight oxygene"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs oxygene">iter_operate  ----------------------<span class="hljs-keyword">iterator</span>/<span class="hljs-keyword">iterator</span>.c <span class="hljs-comment">// 递归处理入口函数</span><br>	process_request-----------------<span class="hljs-keyword">iterator</span>/<span class="hljs-keyword">iterator</span>.c <span class="hljs-comment">// 请求处理主要入口点</span><br>		iter_handle-----------------<span class="hljs-keyword">iterator</span>/<span class="hljs-keyword">iterator</span>.c <span class="hljs-comment">// 循环状态机，当前线程根据状态进行forward等查询，直到获取结果并返回信息</span><br></code></pre></td></tr></table></figure>

<h4 id="iterator查询结果缓存过程"><a href="#iterator查询结果缓存过程" class="headerlink" title="iterator查询结果缓存过程"></a>iterator查询结果缓存过程</h4><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">mesh_run</span><span class="hljs-params">()</span></span>--------------services/mesh<span class="hljs-selector-class">.c</span> <br>	iter_operate--------------------iterator/iterator<span class="hljs-selector-class">.c</span><br>		iter_dns_store----------------iterator/iter_util<span class="hljs-selector-class">.c</span> <span class="hljs-comment">// iter封装的存储接口</span><br>			dns_cache_store-----------services/cache/dns<span class="hljs-selector-class">.c</span> <span class="hljs-comment">// 全局可用存储接口，根据参数决定是否只存储rrset或rrset和msg都存储</span><br>				dns_cache_store_msg---services/cache/dns<span class="hljs-selector-class">.c</span> <span class="hljs-comment">// rrset和msg都存储接口</span><br></code></pre></td></tr></table></figure>

<h2 id="remote-远程请求accept设置过程"><a href="#remote-远程请求accept设置过程" class="headerlink" title="remote 远程请求accept设置过程"></a>remote 远程请求accept设置过程</h2><p>只有线程序号为0的主线程进行accept请求处理，其他未业务请求</p>
<figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">worker_start_accept<span class="hljs-params">--------worker</span>.c     <span class="hljs-string">//</span> 启动监听并accept<br>    daemon_remote_start_accept<span class="hljs-params">--------daemon/remote</span>.c     <span class="hljs-string">//</span> 根据配置的地址列表进行监听处理<br>        comm_point_start_listening<span class="hljs-params">------util/netevent</span>.c   <span class="hljs-string">//</span><br></code></pre></td></tr></table></figure>

<h2 id="remote-control-服务端启动流程"><a href="#remote-control-服务端启动流程" class="headerlink" title="remote control 服务端启动流程"></a>remote control 服务端启动流程</h2><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs jboss-cli">worker_init<span class="hljs-params">--------------------------------worker</span>.c     <span class="hljs-string">//</span> 工作线程初始化，worker_start_accept，<br>	worker_start_accept<span class="hljs-params">--------------------worker</span>.c     <span class="hljs-string">//</span> 启动监听并accept<br>		daemon_remote_start_accept<span class="hljs-params">-------daemon/remote</span>.c <span class="hljs-string">//</span> 在线程0中启动 remote_control 相关监听<br>			handle_req<span class="hljs-params">------------------daemon/remote</span>.c  <span class="hljs-string">//</span> 启动处理请求处理过程<br>				execute_cmd <span class="hljs-params">------------daemon/remote</span>.c  <span class="hljs-string">//</span> 处理具体的请求<br></code></pre></td></tr></table></figure>


<h2 id="耗时相关代码"><a href="#耗时相关代码" class="headerlink" title="耗时相关代码"></a>耗时相关代码</h2><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs awk">daemon_fork							daemon/daemon.c<br>	daemon_setup_modules 			daemon/daemon.c<br>		modstack_setup    			services/modstack.c<br>			modstack_desetup<br>				fptr_whitelist_mod_deinit<br>				(*stack-&gt;mod[i]-&gt;deinit)(env, i);<br>					subnetmod_deinit    edns-subnet/subnetmod.c<br>						slabhash_delete 				 util<span class="hljs-regexp">/storage/</span>slabhash.c   <span class="hljs-regexp">//</span> 此函数修改为自定义的qy_slabhash_delete函数, 实际耗时可能在此处<br>							lruhash_delete				util<span class="hljs-regexp">/storage/</span>lruhash.c<br>								bin_delete               util<span class="hljs-regexp">/storage/</span>lruhash.c<br></code></pre></td></tr></table></figure>



<h1 id="重要概念"><a href="#重要概念" class="headerlink" title="重要概念"></a>重要概念</h1><h2 id="module（即插件）"><a href="#module（即插件）" class="headerlink" title="module（即插件）"></a>module（即插件）</h2><p> unbound 中的 <code>module</code> 即模块(插件)。支持以下模块</p>
<table>
<thead>
<tr>
<th>模块名</th>
<th>作用</th>
<th>其他</th>
</tr>
</thead>
<tbody><tr>
<td>validator</td>
<td>用于验证DNSSEC签名有效性，确保DNS解析查询结果的完整性和不可篡改性</td>
<td></td>
</tr>
<tr>
<td>respip</td>
<td>允许使用ACL（访问控制列表）限制哪些IP地址可以访问特定的域名 或 基于IP修改响应结果</td>
<td></td>
</tr>
<tr>
<td>pythonmod</td>
<td>允许以Python脚本的形式扩展Unbound功能，可以实现自定义的DNS处理逻辑</td>
<td></td>
</tr>
<tr>
<td>iterator</td>
<td>实现Unbound的迭代DNS解析查询功能，向远端DNS服务器递归查询所需DNS记录</td>
<td></td>
</tr>
<tr>
<td>subnet</td>
<td>用于配置Unbound服务器的子网访问控制策略，允许或禁止指定子网的访问</td>
<td></td>
</tr>
<tr>
<td>subnetcache</td>
<td>实现了支持不同子网对 DNS 解析结果进行缓存的功能。当一个请求来自于一个特定的子网时，subnetcache 模块会将 DNS 解析结果缓存下来，以便以后在该子网中的相同请求中能够快速响应</td>
<td>编译支持ECS时默认开启此模块</td>
</tr>
<tr>
<td>subnetcachedb</td>
<td>支持对存储数据进行加密，保护缓存数据的隐私和安全。可以与 subnetcache 模块结合使用，以提供更高效的DNS解析缓存策略</td>
<td></td>
</tr>
<tr>
<td>dns64</td>
<td>实现DNS64代理，将IPv4 DNS请求转换为IPv6地址并返回响应</td>
<td></td>
</tr>
<tr>
<td>rpz</td>
<td>实现RPZ（Responsibility Provenance Zone）功能，支持自定义DNS黑名单和白名单</td>
<td></td>
</tr>
<tr>
<td>prefetch</td>
<td>提前查询DNS记录，以缩短DNS响应时间，提高用户的访问速度</td>
<td></td>
</tr>
</tbody></table>
<p>这些模块可以通过配置文件中的 <code>module-config</code> 选项进行加载和配置，以实现各种不同的功能。同时，Unbound还支持许多其他模块，如dnstap模块、subnetcachedb模块、python_certgen模块等，可以根据需要选择适当的模块来实现自己的需求。</p>
<ul>
<li>1.6.7版 编译加–enable-subnet后默认将启动三个插件，按执行顺序分别是subnetcache,validator,iterator,所以mesh_run的执行顺序是按照这个插件顺序执行的。</li>
</ul>
<h1 id="常用测试代码"><a href="#常用测试代码" class="headerlink" title="常用测试代码"></a>常用测试代码</h1><ul>
<li>获取连接客户端ip地址<figure class="highlight clojure"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs clojure">&#123;<br>    char ip[<span class="hljs-number">128</span>]<span class="hljs-comment">;</span><br>    struct sockaddr_storage *addr = &amp;repinfo-&gt;addr;<br>    addr_to_str(<span class="hljs-name">addr</span>, repinfo-&gt;addrlen, ip, sizeof(<span class="hljs-name">ip</span>))<span class="hljs-comment">;</span><br>    log_info(<span class="hljs-string">&quot;@@@@Client IP= %s#%d\n&quot;</span>, ip,<br>            ntohs(((<span class="hljs-name">struct</span> sockaddr_in *)addr)-&gt;sin_port))<span class="hljs-comment">;</span><br>&#125;<br></code></pre></td></tr></table></figure></li>
</ul>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91/">软件开发</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/dns/">dns</a>
                    
                      <a class="hover-with-bg" href="/tags/unbound/">unbound</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2023/04/11/04DevOps/25ipset%E4%B8%8Eiptables/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">ipset与iptables</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2023/01/16/04DevOps/24%E9%80%9A%E9%85%8D%E7%AC%A6%E5%92%8C%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/">
                        <span class="hidden-mobile">通配符和正则表达式的区别</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/js/local-search.js" ></script>



  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
        typing(title);
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>


</body>
</html>
